<?php
declare (strict_types = 1);

namespace app\live\model;

use app\common\model\Config;
use app\common\self\MyJob;
use think\Model;

/**
 * @mixin \think\Model
 */
class LiveBroadcastGoods extends Model
{
    public $page = '';//分页数据
    public $count = '';//数据总数
    public $error = '';//报错
    public $rekey = 'livebroadcastgoods_';


    /*
     * 获取直播商品列表
     */
    public function getList($id)
    {
        try{
            $data = Input('post.');
            if(empty($data['start'])||empty($data['end'])) exception('请先选择直播开始/结束时间!');
            $data['start'] = strtotime(date('Y-m-d'. $data['start']));
            $data['end'] = strtotime(date('Y-m-d'. $data['end']));
            //查询条件
            if(!empty($data['name'])){
                $where[] = ['name','like','%'.trim($data['name']).'%'];
            }
            $where[] = ['status', '=', 1];
            $where[] = ['wx_status', '=', 2];
            $where[] = ['is_delete', '=', 0];
            $desc = 'sort';
            if(!empty($data['orderby'])&&$data['orderby'] == 1) $desc = 'is_hot';
            if(!empty($data['orderby'])&&$data['orderby'] == 2) $desc = 'price2 desc,commission';
            if(!empty($data['orderby'])&&$data['orderby'] == 3) $desc = 'price2';
            //if(!empty($data['orderby'])&&$data['orderby'] == 4) $desc = 'sort';
            $desc .= ' '.(isset($data['desc'])&&$data['desc'] == 'asc' ? 'asc' : 'desc');
            $limit = isset($data['limit'])&&!empty($data['limit']) ? $data['limit'] : 15;//每页显示数据
            $query = ['page' => (isset($data['page']) ? $data['page'] : 1)];//分页参数
            $field = 'id,name,cover,goods_id,commission,priceType,price,price2';
            $item = $this->where($where)->field($field)->order($desc)->paginate($limit, false, array('query'=>$query));
            $list = empty($item) ? array():$item->toArray();
            if(!empty($list['data'])){
                if(!empty($id)){
                    $redis = getRedis();
                    $info = $redis->hGet($this->rekey.$id, $data['start'].'-'.$data['end']);
                    if(!empty($info)) $info = json_decode($info,true);
                }
                foreach($list['data'] as $k=>$v){
                    $list['data'][$k]['name'] = emojiDecode($v['name']);
                    $list['data'][$k]['cover'] = getApiDominUrl($v['cover']);
                    $list['data'][$k]['commission'] = getformat($v['price2']*$v['commission']*100);
                    $is_check = $this->checkGoods($v['goods_id'],['start'=>$data['start'],'end'=>$data['end']]);
                    $list['data'][$k]['status'] = ($is_check==false)? 2 : 1;
                    if(!empty($info)&&in_array($v['goods_id'],$info)) $list['goods'][] = $v;
                }
                if(!isset($list['goods'])) $list['goods'] = [];
            }
            return $list;
        }catch (\Exception $e){
            if(stristr($e->getMessage(),'SQLSTATE')){
                $this->error = '数据走丢了，请稍后再试！';
            }else $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 选择直播商品->redis
     */
    public function selectGoodsById($id)
    {
        try{
            if(empty($id)) exception('找不到该用户!');
            $data = Input('post.');
            if(empty($data['goods_id'])||!is_numeric($data['goods_id'])) exception('未选择商品!');
            if(empty($data['start'])||empty($data['end'])) exception('请先选择直播开始/结束时间!');
            $goodsInfo = $this->where(['goods_id'=>$data['goods_id'],'is_delete'=>0])->find();
            if(empty($goodsInfo)) exception('选择的商品不存在!');
            $start = strtotime(date('Y-m-d'. $data['start']));
            $end = strtotime(date('Y-m-d'. $data['end']));
            $timeKey = $start.'-'.$end;
            if($start < (time()+900)) exception('请提前15分钟申请直播，开始时间必须在15分钟以后的!');
            if($end - $start < 1800) exception('开播时间不能小于30分钟!');
            $redis_key = $this->rekey.date('Ymd').'_'.$data['goods_id'];
            $redis = getRedis();
            $max = $redis->hGet($this->rekey.$id, $timeKey);
            if(!empty($max)) $max = json_decode($max,true);
            else $max = [];
            $maxC = (new Config())->toData('live');
            if(count($max) >= $maxC['goods_limit']) exception("每场直播只能申请{$maxC['goods_limit']}件商品!");
            $is_check = $this->checkGoods($data['goods_id'], ['start'=>$start, 'end'=>$end],$id);
            if(!$is_check) exception('该商品在这个时间段已被选取!');
            if($is_check == 2) exception('已添加成功，请勿重复添加!');
            $info = $redis->hSet($redis_key, $timeKey, $id);
            if($info == false) exception('选取商品失败，请重试!');
            else{
                if(!empty($data['goods_key'])) $redis->hDel($redis_key, $data['goods_key']);
                $is_true = false;
                if(!empty($max)){
                    foreach($max as $k=>$v)
                        if($v == $data['goods_id']) $is_true = true;
                }
                if($is_true == false){
                    $max[] = $data['goods_id'];
                    $redis->hSet($this->rekey.$id, $timeKey, json_encode($max));
                }
            }
            $ret = $redis->ttl($redis_key);
            if ($ret === -1) $redis->expire($redis_key, 3600*24*3);
            $v = MyJob::pushQueue('LiveBroadcastGoodsJob',['id'=> $data['goods_id'],'uid'=>$id,'key'=>$timeKey],7200);
            fileLog('推送日志ok---'.$v,'LiveBroadcastGoodsJob.log');
            return ['goods_key'=>$timeKey];
        }catch (\Exception $e){
            $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 删除已选择的直播商品->redis
     */
    public function delGoodsById($id)
    {
        try{
            if(empty($id)) exception('找不到该用户!');
            $data = Input('post.');
            if(empty($data['goods_id'])||!is_numeric($data['goods_id'])) exception('请选择要移除的商品!');
            if(empty($data['goods_key'])) exception('缺少已选择商品的key!');
            $redis_key = $this->rekey.date('Ymd').'_'.$data['goods_id'];
            $redis = getRedis();
            $info = $redis->hGet($redis_key, $data['goods_key']);
            if($info == false) return true;
            #if($info == false) exception('无法获取要移除的商品!');
            if($info != $id) exception('您未选择该商品，无法移除!');
            $infos = $redis->hDel($redis_key, $data['goods_key']);
            if($infos == false) exception('移除失败!');
            #移除商品redis
            $goods = $redis->hGet($this->rekey.$id, $data['goods_key']);
            if(!empty($goods)){
                $goods = json_decode($goods,true);
                foreach($goods as $k=>$v)
                    if($data['goods_id'] == $v) unset($goods[$k]);
                $redis->hSet($redis_key,$data['goods_key'],json_encode($goods));
            }
            return true;
        }catch (\Exception $e){
            $this->error = $e->getMessage();
            return false;
        }
    }

    /*
     * 检查商品在对应的时间段是否被选择
     * $redis_key redis键
     * $time 开始/结束时间
     */
    public function checkGoods($goods_id,$time,$id=0)
    {
        $start = $time['start'];
        $end = $time['end'];
        $redis_key = $this->rekey.date('Ymd').'_'.$goods_id;
        $redis = getRedis();
        if($id>0){
            $uid = $redis->hGet($redis_key, $time['start'].'-'.$time['end']);
            if($uid == $id) return 2;
        }
        $keys = $redis->hKeys($redis_key);
        if(!empty($keys)){
            foreach($keys as $k=>$v){
                $time = explode('-',$v);
                if($start >= $time[0]&&$start < $time[1]) return false;
                if($end > $time[0]&&$end <= $time[1]) return false;
                if($start <= $time[0]&&$end >= $time[1]) return false;
            }
        }
        return 1;
    }

    /*
     * 获取指定商品对应的直播时间key和uid
     * $goods_id 商品id
     * $time 当前的时间戳
     * $day 日期-拼接的年月日
     * @return $bool|$array 返回false  表示没有 返回数字 表示 对应的直播列表id和时间戳
     */
    public function getReGoods($goods_id,$time = 0,$day=0)
    {
        if(!$time)$time = time();
        $day = empty($day) ? date('Ymd') : $day;
        $redis_key = $this->rekey.$day.'_'.$goods_id;
        $redis = getRedis();
        $info  = $redis->hGetAll($redis_key);
        if(!$info || !is_array($info)) return false;
        if($info && is_array($info)){
            foreach($info as $key => $item){
                $list_time = explode('-',$key);
                if( $time - $list_time[0] > 0 && $list_time[1] - $time > 0) return [
                    'uid' => $item,
                    'start_time' => $list_time[0],
                    'end_time' => $list_time[1]
                ];
            }
        }
        return false;
    }

    /*
     * 检查商品在对应的时间段是否被选择
     * $redis_key redis键
     * $time 开始/结束时间
     * $key 之前存储的字段
     */
    public function checkGoodsAndSelect($goods,$key,$time,$id=0)
    {
        if(empty($goods)) return false;
        $is_check = null;
        $redis = getRedis();
        $timeKey = $time['start'].'-'.$time['end'];
        if(is_array($goods)){
            foreach($goods as $v){
                if(!empty($v)){
                    $redis_key = $this->rekey.date('Ymd').'_'.$v;
                    if($key != $timeKey) $del = $redis->hDel($redis_key, $key);
                    $info = $redis->hGet($redis_key, $timeKey); #获取redis存储的id
                    if($info == false){
                        $is_check[$v] = $this->checkRedis($redis,$v,$time,$redis_key,$timeKey,$id);
                        if($is_check[$v] == false) exception('由于更改直播时间需要重新选择商品!');
                    }elseif($info != $id) exception('由于更改直播时间需要重新选择商品!');
                    else $is_check[$v] = true;
                }
            }
        }else{
            $redis_key = $this->rekey.date('Ymd').'_'.$goods;
            if($key != $timeKey) $del = $redis->hDel($redis_key, $key);
            $info = $redis->hGet($redis_key, $timeKey); #获取redis存储的id
            if($info == false){
                $is_check = $this->checkRedis($redis,$goods,$time,$redis_key,$timeKey,$id);
                if($is_check == false) exception('由于更改直播时间需要重新选择商品!');
            }elseif($info != $id) exception('由于更改直播时间需要重新选择商品!');
            else $is_check = true;
        }
        return $is_check;
    }

    public function checkRedis(\Redis $redis,$goods,$time,$redis_key,$timeKey,$id)
    {
        $is_check = $this->checkGoods($goods, $time);
        if(!$is_check) return false;
        else{
            $info = $redis->hSet($redis_key, $timeKey, $id);
            if($info == false) return false;
            else{
                if(!empty($key)) $redis->hDel($redis_key,$key);
                $goodslist = $redis->hGet($this->rekey.$id,$timeKey);
                if(!empty($goodslist)){
                    $goodslist = json_decode($goodslist,true);
                    $is_true = false;
                    foreach($goodslist as $k=>$v){
                        if($v == $goods) $is_true = true;
                    }
                    if($is_true == false){
                        $goodslist[] = $goods;
                        $redis->hSet($this->rekey.$id, $timeKey, json_encode($goodslist));
                    }
                }
            }
        }
        $ret = $redis->ttl($redis_key);
        if ($ret === -1) $redis->expire($redis_key, 3600*24*3);
        return $is_check;
    }
}
